/*
 * Created on 07.12.2003
 */
package observations;

import java.util.*;

/**
 <code>PhenomenonType</code> Is a particular type of phenomenon, e.g.
 * 'bloodpressure' or 'heartrate'. The class is part of the Fowler-patterns
 * 'Measurement' and 'Observation'.
 
 @author Sascha Hemminger
 @version 2004-09-10
 @see observations.Measurement
 */
public class PhenomenonType extends DomainObject {

  /**
   * Searches a type by name.
   
   @param name
   *            name of the type
   @return the found type
   */
  public static PhenomenonType get(String name) {
    return (PhenomenonTypeRegistrar.get("PhenomenonType", name);
  }
  private Vector phenomena = new Vector();

  private QuantityRange validRange;

  /**
   * Constructs a PhenomenonType object with name.
   
   @param name
   *            name of the type
   @see observations.DomainObject#DomainObject(String)
   */
  public PhenomenonType(String name) {
    super(name);
  }

  void friendPhenomenonAdd(Phenomenon newPhenomenon) {
    phenomena.addElement(newPhenomenon);
  }

  /**
   * Gives a hashtable of all phenomena.
   
   @return the hashtable with all phenomena
   */
  public Hashtable getMappingTable() {
    Hashtable result = new Hashtable();
    Enumeration e = getPhenomenaEnumeration();
    while (e.hasMoreElements()) {
      Phenomenon each = (Phenomenone.nextElement();
      result.put(each.getName(), each);
    }
    return result;
  }

  /**
   * Gives all phenomena for the type.
   
   @return enumeration of all phenomena
   */
  public Enumeration getPhenomenaEnumeration() {
    return phenomena.elements();
  }

  /**
   * Searches the phenomenon which includes a particular quantity.
   
   @param quantity
   *            quantity to test
   @return the phenomenon of a particular quantity
   */
  public Phenomenon getPhenomenonIncluding(Quantity quantity) {
    Enumeration e = getPhenomenaEnumeration();
    while (e.hasMoreElements()) {
      Phenomenon each = (Phenomenone.nextElement();
      if (each.includes(quantity))
        return each;
    }
    return null;
  }

  /**
   * Searches a particular phenomenon by name.
   
   @param name
   *            name of the phenomenon
   @return phenomenon if found else null
   */
  public Phenomenon getPhenomenonNamed(String name) {
    Enumeration phenomenonEnum = getPhenomenaEnumeration();
    if (!phenomenonEnum.hasMoreElements())
      return null;
    Phenomenon result = null;
    do {
      Phenomenon each = (PhenomenonphenomenonEnum.nextElement();
      if (each.getName() == name)
        result = each;
    while (phenomenonEnum.hasMoreElements());
    return result;
  }

  /**
   * Saves the type to main memory.
   
   @return the type.
   */
  public PhenomenonType persist() {
    Registrar.add("PhenomenonType"this);
    return this;
  }

  /**
   * Sets the valid phenomena, e.g. 'low' and 'high'.
   
   @param names
   *            phenomena's names
   */
  public void setPhenomena(String[] names) {
    for (int i = 0; i < names.length; ++i)
      new Phenomenon(names[i]this);
  }

  /**
   * Sets the overall range including all phenomena, e.g. if the valid range
   * is 0 - 200 mm/Hg, there may be two phenomena 'low' and 'high' with ranges
   * 0 - 100 mm/Hg and 100 - 200 mm/Hg.
   
   @param range
   *            the overall range of the type
   */
  public void setValidRange(QuantityRange range) {
    validRange = range;
  }

  /**
   * Tests whether the quantity is included in the types over all range.
   
   @param quantity
   *            quantity to test
   @return true if the quantity is a valid quantity
   */
  public boolean validRangeIncludes(Quantity quantity) {
    if (validRange == null)
      return true;
    return validRange.includes(quantity);
  }
}